Step1: 提取Todo, TodoList 组件

//修改前:
<ul>
    {visibleTodos.map(todo => 
       <li key={todo.id} 
         onClick={() =>{
           store.dispatch({
             type: 'TOGGLE_TODO',
             id: todo.id
           });
         }}
         style={{
                textDecoration:
                todo.completed ? 
                  'line-through' : 'none'
               }}>
         {todo.text}
       </li>
     )}
</ul>       //**/

//修改后
const Todo = ({
  onClick,
  completed,
  text
}) => (
  <li 
    onClick={onClick}
    style={{
      textDecoration:
      completed ? 
        'line-through' : 'none'
     }}>
    {text}
  </li>
);

const TodoList = ({
  todos,
  onTodoClick
}) => (
  <ul>
  {todos.map(todo =>
    <Todo 
      key={todo.id}
      {...todo}
      onClick={() => onTodoClick(todo.id)}
    />
  )}
  </ul>     //**/
);

<TodoList
    todos={visibleTodos}
    onTodoClick={id =>
        store.despatch({
        type: 'TOGGLE_TODO',
        id
        })
    } />

Step2: 提取Add Todo 组件

//修改前
<input ref={node => {
this.input = node;
}} />
<button onClick={() => {
store.dispatch({
type: 'ADD_TODO',
text: this.input.value,
id: nextTodoId++
});
}}>
Add Todo
</button>

//修改后
const AddTodo = ({
  onAddClick
}) => {
  let input;

  return (
    <div>
      <input ref={node => {
        input = node;
        }} />
      <button onClick={() => {
        onAddClick(input.value);
        input.value = '';
        }}>
      Add Todo
      </button>
    </div>
  );
};

<AddTodo
    onAddClick={ text =>
        store.disptch({
            type: 'ADD_TODO',
            id: nextTodoId++,
            text
        })
    }
/>
//修改前:
const FilterLink = ({filter, children, currentFilter}) => {
  if (filter === currentFilter){
    return <span>{children}</span>;
  }
  return (
    <a href='#'
      onClick={e => {
        e.preventDefault();
        store.dispatch({
          type: 'SET_VISIBILITY_FILTER',
          filter
        });
    }}>
      {children}
    </a>
  );
}

...

<p>
    Show: 
    {' '}
    <FilterLink filter='SHOW_ALL' currentFilter={visibilityFilter}>ALL</FilterLink>
    {' '}
    <FilterLink filter='SHOW_ACTIVE' currentFilter={visibilityFilter}>Active</FilterLink>
    {' '}
    <FilterLink filter='SHOW_COMPLETED' currentFilter={visibilityFilter}>Completed</FilterLink>
</p>

//修改后:

const Footer = ({
  visibilityFilter,
  onFilterClick
}) => {
  return(
    <p>
      Show: 
      {' '}
      <FilterLink 
        filter='SHOW_ALL' 
        currentFilter={visibilityFilter} 
        onClick={onFilterClick}>ALL</FilterLink>
      {' '}
      <FilterLink
        filter='SHOW_ACTIVE' 
        currentFilter={visibilityFilter} 
        onClick={onFilterClick>Active</FilterLink>
      {' '}
      <FilterLink
        filter='SHOW_COMPLETED' 
        currentFilter={visibilityFilter} 
        onClick={onFilterClick>Completed</FilterLink>
    </p>
  );
}

const FilterLink = ({
  filter, 
  children, 
  currentFilter,
  onClick   //++
}) => {
  if (filter === currentFilter){
    return <span>{children}</span>;
  }
  return (
    <a href='#'
      onClick={ e => {
        e.preventDefault();
        onClick(filter);        //++
    }}>
      {children}
    </a>
  );
};

<Footer
   visibilityFilter={visibilityFilter}
   onFilterClick={filter =>
     store.dispatch({
       type: 'SET_VISIBILITY_FILTER',
       filter
     })
   }
 />

Step4: 提取TodoApp 组件

//修改前:

class TodoApp extends Component {
  render() {
    const { todos,visibilityFilter } = this.props;
    const visibleTodos = getVisibleTodos(todos,visibilityFilter);
    return (
      <div>
        <input ref={node => {
          this.input = node;
      }} />
        <button onClick={() => {
          store.dispatch({
            type: 'ADD_TODO',
            text: this.input.value,
            id: nextTodoId++
          });
         }}>
           Add Todo
         </button>
         <ul>
           {visibleTodos.map(todo => 
             <li key={todo.id} 
               onClick={() =>{
                 store.dispatch({
                   type: 'TOGGLE_TODO',
                   id: todo.id
                 });
               }}
               style={{
                      textDecoration:
                      todo.completed ? 
                        'line-through' : 'none'
                     }}>
               {todo.text}
             </li>
           )}
         </ul>  
         <p>
         Show: 
         {' '}
          <FilterLink filter='SHOW_ALL' currentFilter={visibilityFilter}>ALL</FilterLink>
         {' '}
          <FilterLink filter='SHOW_ACTIVE' currentFilter={visibilityFilter}>Active</FilterLink>
         {' '}
          <FilterLink filter='SHOW_COMPLETED' currentFilter={visibilityFilter}>Completed</FilterLink>
          </p>
      </div>
    );
  };
};

//修改后:
// TodoApp 组件
const TodoApp = ({
  todos,
  visibilityFilter
}) => (
  <div>
    <AddTodo
      onAddClick={text =>
        store.dispatch({
          type: 'ADD_TODO',
          id: nextTodoId++,
          text
        })
      }
    />
    <TodoList
      todos={getVisibleTodos(todos,visibilityFilter)}
      onTodoClick={id =>
        store.dispatch({
          type: 'TOGGLE_TODO',
          id
        })
      } />
    <Footer 
      visibilityFilter={visibilityFilter}
      onFilterClick={filter => {
        store.dispatch({
          type: 'SET_VISIBILITY_FILTER',
          filter
        });
      }} />
  </div>
);

//最终代码:http://jsbin.com/pusadi/edit?html,js,output